#include "crc8.h"
/*
 * CRC Calculation

An 8-bit CRC polynomial is used for checking both read and write access. It allows detection of up to eight single-bit

errors. The CRC8-ATM polynomial with an initial value of zero is applied LSB to MSB, including the sync and addressing

byte. The sync nibble is assumed to be always correct. The TMC5240 responds only to correctly transmitted datagrams

containing its own node address. It increases its datagram counter for each correctly received write access datagram.

CRC = x8 + x2 + x1 + x0

Serial calculation example

CRC = (CRC << 1) OR (CRC.7 XOR CRC.1 XOR CRC.0 XOR [new incoming bit])

C-Code Example for CRC Calculation

void swuart_calcCRC(UCHAR* datagram, UCHAR datagramLength)

{

int i,j;

UCHAR* crc = datagram + (datagramLength-1); // CRC located in last byte of message

UCHAR currentByte;

*crc = 0;

for (i = 0; i<(datagramLength-1); i++) { // Execute for all bytes of a message

currentByte = datagram[i]; // Retrieve a byte to be sent from Array

for (j = 0; j<8; j++) {

if ((*crc >> 7) ^ (currentByte&0x01)) // update CRC based result of XOR operation

{

*crc = (*crc << 1) ^ 0x07;

}

else

{

*crc = (*crc << 1);

}

currentByte = currentByte >> 1;

} // for CRC bit

} // for message byte

}将这crc8atm函数实现写到CRC/crc8里面去
*/


// CRC8-ATM: 多项式 0x07 (x^8 + x^2 + x + 1)，初始值 0x00
// 位序：按LSB到MSB输入（每字节低位先处理），与示例一致
uint8_t CRC8_ATM_Calc(const uint8_t* data, uint16_t len) {
    uint8_t crc = 0x00; // 初始值
    for (uint16_t i = 0; i < len; ++i) {
        uint8_t currentByte = data[i];
        for (int j = 0; j < 8; ++j) {
            if (((crc >> 7) & 0x01) ^ (currentByte & 0x01)) {
                crc = (uint8_t)((crc << 1) ^ 0x07);
            } else {
                crc = (uint8_t)(crc << 1);
            }
            currentByte >>= 1; // 取下一位（LSB -> MSB）
        }
    }
    return crc;
}

// 将CRC写入报文最后一个字节（最后一字节为CRC位置，不参与计算）
void CRC8_ATM_UpdateLastByte(uint8_t* datagram, uint16_t datagramLength) {
    if (datagram == 0 || datagramLength == 0) return;
    uint16_t payloadLen = (datagramLength > 0) ? (datagramLength - 1) : 0;
    uint8_t crc = CRC8_ATM_Calc(datagram, payloadLen);
    datagram[datagramLength - 1] = crc;
}